返回红宝书
  • 免费答疑QQ群:9990960
  • 网易云课堂免费视频
    • 1. 一些概念
    • 2. 单系统登录
    • 3. SSO登录实现方式
    • 4. SAML 方式
    • 5. AccessToken vs RefreshToken
    • 6. 常见登陆发方式
    • 7. OpenID
    • 8. OAuth
    • 9. 跨域cookie
      • 9.1. 利用HTML的script标签跨域写Cookie
      • 9.2. 通过URL参数实现跨域信息传递
      • 9.3. 读取其它域的Cookie
    • 10. Token携带方式
    • 11. JWT
    • 12. Python Social Auth
    程序常用登录验证
    • Docs »
    • 9. 跨域cookie
    • View page source

    9. 跨域cookie¶

    在使用cookie做访问凭证的网站中,经常会遇到跨域的问题,本节尝试对此问题简单解读。

    9.1. 利用HTML的script标签跨域写Cookie¶

    比如当前域是www.a.com,下面的script标签是跨域写cookie的核心,通过此标签实现了向www.b.com域写入cookie:

    <script type="text/javascript" src="http://www.b.com/setCookie?cname=token&cval=123456"></script>
    
    • P3P协议 P3P是一种被称为个人隐私安全平台项目(the Platform for Privacy Preferences)的标准,能够保护在线隐私权,使Internet冲浪者可以选择在浏览网页时,是否被第三方收集并利用自己的个人信息。如果一个站点不遵守P3P标准的话,那么有关它的Cookies将被自动拒绝,并且P3P还能够自动识破多种Cookies的嵌入方式。p3p是由全球资讯联盟网所开发的。

    • 举个例子:

      我们在访问A网站时,理论上说,我们只能把Cookie信息保存到A站域名下,而不能写入到B网站下。如果想要跨域读写Cookie,只是通过script标签变相访问B网站在一些浏览器是行不通的,此时B网站的服务器应该告诉浏览器允许A网站写入Cookie,否则浏览器将会拒绝执行,这就是P3P协议。

    • 服务端如何告诉浏览器?

      • P3P提供了一种简单的方式 ,来加载用户隐私策略,只要在http响应的头信息中增加

        response.setHeader(“P3P”,”CP=NON DSP COR CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa CONa HISa TELa OTPa OUR UNRa IND UNI COM NAV INT DEM CNT PRE LOC);

        而无需指定隐私策略文件也可以达到指定隐私策略的目的。 CP=后面的字符串分别代表不同的策略信息。

    • 因为P3P协议所以不能保证所有浏览器都能通过script标签方式跨域写Cookie,有的浏览器本身就是拒绝跨域的。

    • 这种方式是不能保证跨域写cookie的成功性。

    9.2. 通过URL参数实现跨域信息传递¶

    • 我们要在A域实现写入token到B域,需要在A域设计一个servlet接收请求

      @WebServlet(name = “tg”) public class Servlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { //获取请求的目标域 String from = request.getParameter(“from”); //生成token, String token = “123456”; //重定向到目标域 response.sendRedirect(from + “?cname=token&cval=” + token); } … }

    • 由a域发起请求,请求地址:http://www.a.com/tg?from=http://www.b.com/set_cookie, 请求后该Servlet会获取from参数的值并生成token最后让客户端重定向到http://www.b.com/set_cookie?cname=token&cval=123456,然后B域的Servlet(“set_cookie”)获取Url参数写入Cookie到客户端,代码:

         //将要写入的cookie项,调用者通过参数传递
        String cookieName = request.getParameter("cname");
        String cookieValue = request.getParameter("cval");
      
        //生成cookie
        Cookie cookie = new Cookie(cookieName,cookieValue);
        cookie.setPath("/");
        //一般可以将domain设置到顶级域
        //cookie.setDomain("www.b.com");
        response.addCookie(cookie);
      

    9.3. 读取其它域的Cookie¶

    • 利用script标签执行另一个域实现的读取cookie方法,script标签返回结果将是变量定义形式的JS代码,每一个变量表示一个cookie项,这些代码加载后,此页面后续JS代码可以直接在script脚本中读取已定义的变量值,即各cookie值。

        <script type="text/javascript" src="http://www.b.com/reaf_cookies"></script>
        HTML页面读取
      
        <script>
        alert(token);
        </script>
      
    • B域的url为/read_cookies的Servlet的实现 如图,首先我们先在request中获取cookie数组,然后for循环遍历拼接为类似var token=’test123’;的字符串。最重要的是设置ContentType为application/javascript

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); StringBuilder stringBuilder = new StringBuilder(); //一定要设置响应类型,否则可能导致IE不解析js直接进行下载操作 response.setContentType(“application/javascript”);

        if (cookies != null) {
            for (Cookie cookie : cookies) {
                //结果类似于这样 var token='123456';
                stringBuilder.append("var ")
                        .append(cookie.getName())
                        .append("=")
                        .append("'")
                        .append(cookie.getValue())
                        .append("'")
                        .append(";");
            }
            response.getWriter().append(stringBuilder.toString());
        }
      

      }

    Next Previous

    © Copyright 2020, 刘大拿